#define VOLTAGE 990
#define TOLERANCE 30
#define POSITIONS 8
#define MUX_OUT_1 2
#define MUX_OUT_2 3
#define MUX_OUT_3 4
#define MUX_ENABLE 5
#define MUX_LOW 8
#define MUX_HIGH 9
#define MUX_IN 0
#define SPEAKER 9
#define DELAY 25

// from example code
void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(SPEAKER, HIGH);
    delayMicroseconds(tone);
    digitalWrite(SPEAKER, LOW);
    delayMicroseconds(tone);
  }
}

// from example code
void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };

  // play the tone corresponding to the note name
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(MUX_OUT_1, OUTPUT);
  pinMode(MUX_OUT_2, OUTPUT);
  pinMode(MUX_OUT_3, OUTPUT);
  pinMode(SPEAKER, OUTPUT);
  pinMode(MUX_IN, INPUT);
}

void loop() {
  delay(DELAY);
  digitalWrite(MUX_LOW, LOW);
  digitalWrite(MUX_HIGH, HIGH);
  digitalWrite(MUX_ENABLE, HIGH);
  
  if (Serial.available() > 0) {
    byte input = Serial.read();
    // hit a field
    if (input == '0') {
        playNote('g', 30); delay(30);
        playNote('b', 30); delay(30);
        playNote('a', 30); delay(30);
        playNote('a', 30); delay(30);
        playNote('C', 30);
    // hit a pole
    } else if (input == '1') {
        playNote('c', 50); delay(50);
        playNote('c', 50);
    } else if (input == '2') {
        playNote('b', 30); 
    }
  }
  
  // sends the header
  Serial.print("FFFFFFFF");
  
  for (int i = 0; i < POSITIONS; i++) {
     digitalWrite(MUX_OUT_1, (i >> 2) % 2 == 1 ? HIGH : LOW);
     digitalWrite(MUX_OUT_2, (i >> 1) % 2 == 1 ? HIGH : LOW);
     digitalWrite(MUX_OUT_3, (i >> 0) % 2 == 1 ? HIGH : LOW);
     delay(DELAY);
     int voltage = analogRead(MUX_IN);
     int count = voltage_to_count(voltage);
     Serial.print(count);
  }
  
  if (digitalRead(6) == HIGH) {
    Serial.print('0');
  } else {
    Serial.print('1'); 
  }
  
  int val = analogRead(1);
  if (val < 350) {
    Serial.print('+');
  } else if (val > 750) {
    Serial.print('-');
  } else {
    Serial.print('0'); 
  }
}

int voltage_to_count(int voltage) {
  if (voltage < 10) {
     return 0; 
  }
  
  int count = 0;
  int temp = voltage;

  for (int i = 2; i < 10; i++) {
    int range = 1023 / i;
    if (voltage + TOLERANCE > range &&
        voltage - TOLERANCE < range) {
        return i-1;
    }
  }
  //while (temp < VOLTAGE) {
  //   temp *= 2;
  //   count++;
  //}
  
  return 0;
}
